<?php

class Utility_CsvFunctions {

    static private $arr_detectable_delimiters = array(
        44,  // comma
        59,  // semi-colon
        124, // pipe
        9,   // tab
    );
    
    static public function parseIntoArray($str_csv, $str_delimiter = null, $str_eol = null, $arr_options = array()) {
    
        if (is_file($str_csv)) {
            $str_csv = file_get_contents($str_csv);
        }

        if(is_null($str_delimiter)) {
            $str_delimiter = self::detectDelimiter($str_csv);
        }
        
        if(empty($str_eol)) {
            $str_eol = "\n";
        }
        
        $int_headers = -1;
        if(isset($arr_options['number_of_headers'])) {
            $int_headers = (int) $arr_options['number_of_headers'];
        }
        
        $arr_headers = null;
        
        $arr_csv = explode($str_eol, $str_csv);
        
        if(($int_headers > 0) && isset($arr_csv[$int_headers-1])) {
            
            $str_csv = $arr_csv[$int_headers-1];
            $str_line = trim($str_csv);
            if(!empty($str_line)) {
                $arr_row = str_getcsv($str_line, $str_delimiter);
                if(!empty($arr_row)) {
                    $arr_headers = $arr_row;
                    foreach($arr_headers as &$str_label) {
                        $str_label = strtolower($str_label);
                    }
                }
            }
        }
        
        if(isset($arr_options['data_keys']) && is_array($arr_options['data_keys'])) {
            $arr_headers = $arr_options['data_keys'];
        }
        
        $arr_data = array();
        
        $int_line = 1;
        foreach($arr_csv as $i => $str_line) {
            
            if($int_line > $int_headers) {
                $str_line = trim($str_line);

                if(!empty($str_line)) {

                    $arr_row = str_getcsv($str_line, $str_delimiter);
                    if(!empty($arr_row)) {

                        if(is_array($arr_headers)) {
                            $arr_row = array_combine($arr_headers, $arr_row);
                        }
                        $arr_data[] = $arr_row;

                    }
                }
            }

            $int_line++;
        }
        
        return $arr_data;
    }
    
    static public function getDetectableDelimiters() {
        return self::$arr_detectable_delimiters;
    }
    
    static public function detectDelimiter($str) {
        
        $str_delimiter = null;
        
        $arr_counts = count_chars($str, 1);
        arsort($arr_counts);
        
        $arr_dectectable = self::getDetectableDelimiters();
        
        $arr_delimiters = array();
        foreach($arr_counts as $int_char => $int_count) {
            if(in_array($int_char, $arr_dectectable)) {
                $arr_delimiters[$int_char] = $int_count;
            }
        }
        
        $int_delimiter = null;
        if(!empty($arr_delimiters)) {
            reset($arr_delimiters);
            $int_delimiter = key($arr_delimiters);
        }
        
        if(!is_null($int_delimiter)) {
            $str_delimiter = chr($int_delimiter);
        }
        
        return $str_delimiter;
    }
    
    static public function generateCsvAsString($arr_data, $str_delimiter = ',', $str_eol = "\n", $str_enclosure = '"') {
        
        $str_csv = null;
        
        if(empty($arr_data)) {
            $str_csv = '';
        } else {
        
            $res = fopen('php://temp', 'r+');
            
            if($res !== false) {
                
                foreach($arr_data as $arr_row) {
                    fputcsv($res, $arr_row, $str_delimiter, $str_enclosure);
                }
                
                rewind($res);
                
                $str_csv = '';
                
                while(($str_buffer = fgets($res)) !== false) {
                    
                    if($str_eol != PHP_EOL) {
                        $str_buffer = substr($str_buffer, 0, (0 - strlen(PHP_EOL))) . $str_eol;
                    }
                    
                    $str_csv .= $str_buffer;
                }
                
            
                fclose($res);
            }
            
        }
        
        return $str_csv;
        
    }

}
